home *** CD-ROM | disk | FTP | other *** search
- ;Version 2.1 1982 Mark S Zachmann
- ;
- ; This program lets you totally remap the
- ; disks on MS-DOS. You can map each side of a logical
- ; drive to any other side or to memory.
- ;
- ; For example, a usual configuration would be
- ; map drive 0, sides 0,1 to drive 0 sides 0,1 (no change)
- ; drive 1, sides 0,1 to drive 1 sides 0,1 "
- ; drive 2, side 0 to segment 4000h
- ; drive 2, side 1 to segment 6800h
- ;
- ; this will let you use 256K for the MS-DOS system, and another
- ; 320K of memory for a double-sided RAM disk, if you have a 512K
- ; board installed. ( for 576K total )
-
- ;**********************************************
- ; to alter this for your system:
- ; change the equates at locations 'DISKPTR'
- ; they come in order (0/0, 1/0, 0/1, 1/1, 0/2, 1/2, 0/3, ...
- ; and each entry says which to map to:
- ;
- ; 0h = side 0/disk 0
- ; 100h = side 1/disk 0
- ; 1h = side 0/disk 1
- ; 101h = side 1/disk 1
- ; ...etc
- ; anything bigger than f00h is treated as a location in RAM,
- ; thus
- ; 4000h = segment beginning at 4000:0000h
- ; 6800h = segment beginning at 6800:0000h
- ; etc
- ;*********************************************
- ; also, 0FFFFh = return an error if this side is selected.
-
- ; for my default setup: (disk A,B normal, C RAMdisk, ...)
- ; Note that the dip switches inside must then be set to
- ; indicate 3 disk drives and 256K of memory. All disk operations
- ; are transparent to the user.
- ; this is for two reasons:
- ;(1) MS-DOS must feel that any RAMdisk memory does not exist
- ;(2) MS-DOS needs to know how many drives (real or otherwise)
- ; there are
- ; Note that the RAM disks must be FORMATted before use, unless
- ; you use DISKCOPY to send data to them.
- ;
- ;
- ; SYNTAX:
-
- ; A>ramdisk creates a ramdisk and writes F6 to each byte
- ; to eliminate possible parity errors on read
- ;
- ; A>ramdisk old creates a ramdisk, but does not overwrite
- ; old data. used if you had to reset
- ; (ctrl-alt-del) for some reason
-
-
- TITLE Double-Sided Diskette Support
- SUBTTL
-
-
- BASE equ 0h ;Base of memory
- DiskInt equ 4Ch ;Offset of int
- DISKETTE_STATUS equ 0441h
- DISK_POINTER equ 078h
- bufr equ 80h ; command line parm address
-
-
- ;first the macro library must be in here
-
- IF1
- Include Interupt.MAC
- ENDIF
-
- ;first macro ----
-
- Prolog DOUBLE
-
- ASSUME DS:DOUBLE,CS:DOUBLE
- ;----------------------------------------
- ;----------------------------------------
- ;----------------------------------------
-
- SUBTTL Diskette I/O Call Entry Point
-
- COMMENT * Actual Entry point
- On entry:
- DL = logical disk number (0-n)
- DH = 0 (side-1)
- On call to disk I/O:
- DL = physical disk number
- DH = side number (0 or 1)
- DH=0 or 1 (1 if DL was odd)
-
- For other registers...
- See Reference Manual p.A-32
-
- IF reference is to memory_disk
- { Case:
- RESET - pass to usual disk reset
- STATUS - " " "
- READ - transfer buffer to memory
- WRITE - transfer memory to buffer
- VERIFY - do nothing (just like BIOS)
- FORMAT - fill sectors(s) with [DISK_BASE+8]
-
- Always return successful completion code.
- unless signaled otherwise by 0xFFFF assegment
- }
-
- Upon return, all registers except AX unchanged.
- Memory references also set
- DISKETTE_STATUS to 0.
-
- *
-
- ;---------------------------------------------
- ;
- ; Actual diskette I/O filter routine
- ;
- ;---------------------------------------------
- Main proc far
-
- ENTRY: STI ;Allow interrupts
- push DX ;So we can reset it later
- cmp AH,1 ;Is it disk independent?
- jle USUAL ;Yes, do what is usual.
-
- ; Now figure out which disk is involved.
- ; by table lookup. No validity check here.
- ; The table will return a DX (DH - side, DL - drive)
- ; value for use or > 3FFh which implies a memory
- ; reference, in which case the two bytes
- ; are a starting segment number.
- ; ** Special Case:
- ; if address is FFFF hex (impossible, ROM is there)
- ; we return an error code, so you can use 160K ramdisk
- ; effectively as single sided disk
- ; .Most DOS routines try to read side 2, hence this kludge
- ; for a 160K ramdisk
-
- XCHG BX,DX ;Need BX for indexing
- SHL BL,1 ;*2 for word offset
- add BL,BH ;side parameter
- shl BL,1
- xor BH,BH
- MOV BX,CS:[BX+offset DISKPTR] ;address/map
- xchg BX,DX ;back again
- cmp DX,0FFFFh ;kludge ?
- je Doerror ;generate error, for opposite side
- ;of 160K ramdisk
- cmp DX,03FFh ;is memory ?
- ja short MEMdisk ;yes
-
- ;----------------------------------------------
- ;
- ;Now call the operating system
- ; because call requires disk activity
- ;
- ;-----------------------------------------------
-
- USUAL: pushf ; because OS does IRET
- ;which wastes a stack item.
- call cs:disket ;call BIOS
-
- ;Return to calling routine
-
- ToDOS: pop dx ;old DX value, must be intact
- ret 2 ;keep flags intact
- Main endp
-
- ;----------------------------------------------
- ;
- ; Use memory for disk
- ; On entry: DX - starting SEGMENT
- ; other registers as in BIOS call
- ; old DX on top of stack
- ;
- ; On exit:
- ; All registers returned
- ; to normal. AX set to status, and
- ; DISKETTE_STATUS set to 0.
- ; Also CY = 0, unless segment was FFFFh
- ;
- ;
- ;-----------------------------------------------
-
- Doerror proc near
- clc
- cmp AH,5 ;format operation?
- mov AH,0
- je ToDos ;if format, then say OK
- ;error routine for single
- mov AX,400h ;sided operation of ramdisk
- stc
- jmp short ToDOS ;no need to do the push/pop stuff
- Doerror endp
-
-
- MEMdisk proc near ;usual memory disk, can't return error
- ; First calculate the starting address
- ; DX+CH*100h+CL*20h
- push DI
- push SI
- push DS
- push ES
- push CX
- push BX
- push AX
- CLD ;always increment string moves
-
- ; if parms change then leave reg's alone
- xor AX,AX
- mov AL,CL ;sector
- dec AX ;relative to 0
- mov CL,5
- SHL AX,CL ;*20h
- add AH,CH ;+track*100h
- add AX,DX ;+segment
- mov DS,AX ;now DS contains buffer addr
-
- pop AX ;get AX back, AL has count
- push AX
- xor CX,CX ;how many sectors
- mov CH,AL ;*256 for words to move
-
- ; set up the parameters for DS:SI -> ES:DI
- ; i.e. a read operation
- xor SI,SI ; ->0
- mov DI,BX ; was ES:BX
-
- ; now do the operation
-
- cmp AH,3
- jb short READ
- je short WRITE
- cmp AH,5
- jb short VERIF
- je short FORMAT
- STC ;unknown, set error flag
-
- ;----------------------------------
- ;
- ; Return to DOS by setting status
- ; to 0 (all OK) and then pop'ing
- ; registers (leave flags alone)
- ;
- ;-------------------------------------
-
- Memret label near
- mov AX,Base
- mov DS,AX
- mov BX,DISKETTE_STATUS
- mov BYTE PTR [BX],0
- pop AX
- pop BX
- pop CX
- pop ES
- pop DS
- pop SI
- pop DI
- mov AH,0 ;Status NEC no problems!
- CLC ;impossible to get error
- jmp short ToDOS
- MEMdisk endp
-
-
- ;--------------------------------------
- ;
- ; Memory I/O routines.
- ; On Entry:
- ; ES:DI = DMA address for transfer
- ; DS:SI - buffer address
- ; CX = number of words to transfer
- ;
- ; On Exit:
- ; CY = 0
- ;
- ;------------------------------------------
-
- ;----------------------------------
- ;
- ; Memory read
- ;
- ;----------------------------------
-
- READ proc near
- rep movsw
- jmp short MEMret
- READ endp
-
- ;-----------------------------------------
- ;
- ; Memory write
- ;
- ; On entry as in read
- ;
- ;------------------------------------------
-
- WRITE proc near
- call REVERS ;backwards move
- rep movsw
- jmp short MEMret
- WRITE endp
-
- ;-----------------------------------------
- ;
- ; Memory Verify
- ; note that verify does nothing
- ; if you look at reference manual
- ; p.A-34 it is clear that
- ; verify only tries to read a track!
- ; which must work here
- ;
- ;-----------------------------------------
-
- VERIF proc near
- jmp short MEMret
- VERIF endp
-
- ;---------------------------------------
- ;
- ; Memory Format
- ;
- ;-----------------------------------------
-
- FORMAT proc near
- call REVERS ;source backwards
- mov AX,BASE
- mov DS,AX
- mov BX,DISK_POINTER
- lds BX,dword ptr [BX]
- mov AL,BYTE PTR [BX+8] ; Format char
- mov AH,AL ;Dup
- rep stosw
- jmp short MEMret
- FORMAT endp
-
-
- ;-----------------------------------
- ;
- ; REVERS
- ; Change Direction, i.e.
- ; XCHG DS:SI,ES:DI
- ;
- ;------------------------------------
-
- REVERS proc near
- mov AX,DS
- mov BX,ES
- mov ES,AX
- mov DS,BX
- xchg DI,SI
- ret
- REVERS endp
-
- ;--------------------------------------
- ;
- ; Permanent storage area
- ;
- ;--------------------------------------
-
-
- disket LABEL DWORD
- DW ?
- DW ?
- ;you can patch this (before or after assembly)
- ;or use the 7E and 7F system calls to set this
- ;on the fly
- DISKPTR label WORD
- dw 0,100h,1,101h ;my usual setup
- dw 4000h,6800h ;C disk is all memory
- dw 0FFFFh, 0FFFFh ;D disk is error
- dw 12 dup(0) ;extra
-
- ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ;!!
- ;!! everything after this is temporary
- ;!!
- ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-
- ;---------------------------------------------
- ; This 'subroutine' sets up the operating
- ; system so that the ENTRY routine
- ; can map logical disks into physical
- ; disks and memory.
- ;
- ; Store the old interrupt vector 13h
- ; at an indirect call location 'disket'.
- ; Then replace the vector
- ; with the user entry point (ENTRY).
- ; This has the effect of leaving the
- ; full user routine in memory until
- ; there is a warm start.
- ;
- ; On entry:
- ; DS = origin of program segment
- ; Effect on registers is irrelevant.
- ;
- ;------------------------------------------
-
-
- ; macro ---
-
- Epilog 013h,Disket,DOUBLE
-
- ;---------------------------------
- ;
- ; Fill Memory Disk areas with zero's
- ; for parity
- ;
- ;-----------------------------------
-
- ; if Old then do not fill
- mov AX,CS:zzarg ; first word at 80h
- cmp AL,'O'
- je Nofl
- cmp AL,'o' ;u/l case
- je Nofl
- ;
- ; must not have been an O
- ;
- int 12h ;memory size(K) -> AX
- mov CL,6 ;*64
- shl AX,CL ;gives segment #
- CLD ;upwards
- mov BX,AX ;for loop convenience
- mov DX,0800H ;32K increment
- FILLUP: mov ES,BX
- mov AX,0F6F6h
- xor DI,DI ;from 0 base
- mov CX,4000h ;words/32k
- rep stosw
- mov BX,ES
- add BX,DX
- cmp BH,0B0h ;video yet ?
- jb FILLUP
-
- ;------------------------------------
- ;
- ; Configure the disks
- ;
- ;---------------------------------------
-
- Nofl: jmp CONFIG
- HIMSG: db 'Disk reconfiguration program',13,10
- db ' 1982, MSZachmann',13,10,'$'
-
- ; macro ---
-
- Finish DOUBLE,250
-
- end
- STC ;unknown